﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;
using System.Collections.Specialized;
using System.Net.Cache;

namespace _180FrameWork.Common
{
    public class BaseWebClientHelper : IDisposable
    {
        public static void Init()
        {
            WebRequest.DefaultWebProxy = null;
            System.Net.ServicePointManager.DefaultConnectionLimit = 512;
        }
        
        private int _timeout = 100000;

        /// <summary>
        /// 请求与响应的超时时间
        /// </summary>
        public int Timeout
        {
            get { return this._timeout; }
            set { this._timeout = value; }
        }
        /// <summary>
        /// url中解析参数
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public static NameValueCollection Getparams(string url)
        {
            try
            {
                Uri uri = new Uri(url);
                return HttpUtility.ParseQueryString(uri.Query);
            }
            catch {
                return null;
            }
        }     

        protected bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            //直接确认，否则打不开
            return true;
        }

        protected HttpWebRequest GetWebRequest(string url, string method, IDictionary<string, string> headerparameters = null)
        {
            if (!url.StartsWith("http://") && !url.Contains("https://"))
            {
                url = HttpContext.Current.Request.Url.AbsoluteUri.Replace(HttpContext.Current.Request.Url.PathAndQuery, "") + url;
            }
            HttpWebRequest req = null;

            if (method == "POST")
            {
                var uri = new Uri(url);
            }
            if (url.Contains("https"))
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
                                       | SecurityProtocolType.Tls
                                       | (SecurityProtocolType)0x300 //Tls11
                                       | (SecurityProtocolType)0xC00; //Tls12
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
            }
            else
            {
                req = (HttpWebRequest)WebRequest.Create(url);
            }
            HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
            req.CachePolicy = noCachePolicy;
            req.ServicePoint.Expect100Continue = false;
            req.Method = method;
            req.KeepAlive = false;             
            //req.UserAgent = "qz180";
            req.Timeout = this._timeout;
            //req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            //req.Headers.Add("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
            //req.UserAgent = "Mozilla/5.0 (Windows NT 5.2; rv:12.0) Gecko/20100101 Firefox/12.0";


            //增加头部
            if (headerparameters != null)
            {
                foreach (var key in headerparameters.Keys)
                {
                    switch (key)
                    {
                        case "Accept":
                            req.Accept = headerparameters[key];
                            break;
                        case "Connection":
                            req.Connection = headerparameters[key];
                            break;
                        case "Content-Length":
                            req.ContentLength = long.Parse(headerparameters[key]);
                            break;
                        case "Content-Type":
                            req.ContentType = headerparameters[key];
                            break;
                        case "Expect":
                            req.Expect = headerparameters[key];
                            break;
                        case "Date":
                            req.Date = DateTime.Parse(headerparameters[key]);
                            break;
                        case "Host":
                            req.Host = headerparameters[key];
                            break;
                        case "If-Modified-Since":
                            req.IfModifiedSince = DateTime.Parse(headerparameters[key]);
                            break;
                        case "Referer":
                            req.Referer = headerparameters[key];
                            break;
                        case "Transfer-Encoding":
                            req.TransferEncoding = headerparameters[key];
                            break;
                        case "User-Agent":
                            req.UserAgent = headerparameters[key];
                            break;
                        default:
                            req.Headers.Add(key, headerparameters[key]);
                            break;
                    }                
                }
            }
            
            //
            return req;
        }

        /// <summary>
        /// 把响应流转换为文本。
        /// </summary>
        /// <param name="rsp">响应流对象</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>响应文本</returns>
        protected static string GetResponseAsString(HttpWebResponse rsp, Encoding encoding)
        {
            System.IO.Stream stream = null;
            StreamReader reader = null;
            try
            {
                // 以字符流的方式读取HTTP响应
                stream = rsp.GetResponseStream();
                reader = new StreamReader(stream, encoding);
                return reader.ReadToEnd();
            }
            finally
            {
                // 释放资源
                if (reader != null) reader.Close();
                if (stream != null) stream.Close();
                if (rsp != null) rsp.Close();
            }
        }

        protected static Stream GetResponseAsStream(HttpWebResponse rsp, Encoding encoding)
        {
            System.IO.Stream stream = null;
            BinaryReader reader = null;
            MemoryStream outputStream = new MemoryStream();
            try
            {
                // 以字符流的方式读取HTTP响应
                stream = rsp.GetResponseStream();
                reader = new BinaryReader(stream, encoding);
                byte[] buffer = new byte[1024];
                int bytesRead;
                do
                {
                    bytesRead = stream.Read(buffer, 0, buffer.Length);
                    outputStream.Write(buffer, 0, bytesRead);
                } 
                while (bytesRead != 0);
                outputStream.Position = 0;
                return outputStream;
            }
            finally
            {
                // 释放资源
                if (reader != null) reader.Close();
                if (stream != null) stream.Close();
                if (rsp != null) rsp.Close();
            }
        }
      
        ///// <summary>
        ///// 组装GET请求URL。
        ///// </summary>
        ///// <param name="url">请求地址</param>
        ///// <param name="parameters">请求参数</param>
        ///// <returns>带参数的GET请求URL</returns>
        //protected string BuildGetUrl(string url, IDictionary<string, string> parameters)
        //{
        //    if (parameters != null && parameters.Count > 0)
        //    {
        //        if (url.Contains("?"))
        //        {
        //            url = url + "&" + BuildQuery(parameters);
        //        }
        //        else
        //        {
        //            url = url + "?" + BuildQuery(parameters);
        //        }
        //    }
        //    return url;
        //}

        /// <summary>
        /// 组装普通文本请求参数。
        /// </summary>
        /// <param name="parameters">Key-Value形式请求参数字典</param>
        /// <returns>URL编码后的请求数据</returns>
        protected static string BuildQueryIDictionary(IDictionary<string, string> parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;

            IEnumerator<KeyValuePair<string, string>> dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                string value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }

                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
                    hasParam = true;
                }
            }

            return postData.ToString();
        }

        /// <summary>
        /// 组装普通文本请求参数。
        /// </summary>
        /// <param name="parameters">Key-Value形式请求参数字典</param>
        /// <returns>URL编码后的请求数据</returns>
        protected static string BuildQuery(IDictionary<string, object> parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;

            foreach (var p in parameters)
            {
                string name = p.Key;
                string value = p.Value.ToStr();
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }

                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
                    hasParam = true;
                }
            }

            return postData.ToString();
        }

        /// <summary>
        /// 组装普通文本请求参数。
        /// </summary>
        /// <param name="parameters">Key-Value形式请求参数字典</param>
        /// <returns>URL编码后的请求数据</returns>
        protected static string BuildQuery(object parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;

            foreach (var p in parameters.GetType().GetProperties())
            {
                string name = p.Name;
                string value = p.GetValue(parameters, null).ToStr();
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }

                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
                    hasParam = true;
                }
            }
            return postData.ToString();
        }

        public void Dispose()
        {
            
        }
    }
}
